﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using IridiumDB.Model;
using System.IO;
using System.Globalization;

namespace IridiumDB.Repository
{
    public class LocationRepository : BaseXmlRepository
    {
        private String _datafile = "|DataDirectory|Locations.xml";
        private XDocument _doc;
        //private String _datafile = @"C:\Documents and Settings\Administrator\My Documents\Visual Studio 2008\Projects\FlaresAtHand\IridiumDB\Locations.xml";
        //private String _datafile = "Locations.xml";

        private const String ElementName_ID = "ID";
        private const String ElementName_Name = "LocationName";
        private const String ElementName_Url = "LocationUrl";
        private const String ElementName_GpsLat = "GpsLat";
        private const String ElementName_GpsLong = "GpsLong";
        private const String ElementName_Duration = "Duration";
        private const String ElementName_Altitude = "Altitude";
        private const String ElementName_Timezone = "Timezone";

        public LocationRepository()
        {
            _datafile = this.SetUpDataFile("Locations.xml", "Locations", "1.0", false);
            _doc = XDocument.Load(_datafile);
        }

        public void Create(Location item)
        {
            //Manipulate
            if (item.ID == Guid.Empty)
                item.ID = Guid.NewGuid();
            XElement xml = ItemToXElement(item);
            _doc.Element("Locations").Add(xml);

            //Save
            _doc.Save(_datafile);
        }

        public Location FindByName(String name)
        {
            return (from location in _doc.Descendants("Location")
                    where location.Element(ElementName_Name) != null && location.Element(ElementName_Name).Value == name
                    select XElementToItem(location)).SingleOrDefault();
        }

        public Location FindByID(int id)
        {
            return (from location in _doc.Descendants("Location")
                    where location.Element(ElementName_ID) != null && location.Element(ElementName_ID).Value == id.ToString(CultureInfo.InvariantCulture)
                    select XElementToItem(location)).SingleOrDefault();
        }

        public bool Exists(Location item)
        {
            var match = (from location in _doc.Descendants("Location")
                         where location.Element(ElementName_Name) != null && location.Element(ElementName_Name).Value == item.LocationName
                         || (location.Element(ElementName_GpsLat) != null && location.Element(ElementName_GpsLat).Value == item.GpsLat.ToString(CultureInfo.InvariantCulture)
                         && location.Element(ElementName_GpsLong) != null && location.Element(ElementName_GpsLong).Value == item.GpsLong.ToString(CultureInfo.InvariantCulture))
                         select location).SingleOrDefault();

            return match != null;
        }

        public List<Location> FindAll()
        {
            return (from location in _doc.Descendants("Location")
                    select XElementToItem(location)).ToList();
        }

        private XElement ItemToXElement(Location item)
        {
            XElement xml = new XElement("Location",
                new XElement(ElementName_ID, item.ID),
                new XElement(ElementName_Name, item.LocationName),
                new XElement(ElementName_GpsLat, item.GpsLat),
                new XElement(ElementName_GpsLong, item.GpsLong),
                new XElement(ElementName_Duration, item.PreviewDuration),
                new XElement(ElementName_Altitude, item.Altitude),
                new XElement(ElementName_Timezone, item.TimezoneName)
                );
            return xml;
        }

        private Location XElementToItem(XElement element)
        {
            String Timezone = GetString(element, ElementName_Timezone);
            String Name = GetString(element, ElementName_Name);
            Guid ID = GetGuid(element, ElementName_ID);
            int Altitude = GetInt(element, ElementName_Altitude);
            int Duration = GetInt(element, ElementName_Duration);
            float Lat = GetFloat(element, ElementName_GpsLat);
            float Long = GetFloat(element, ElementName_GpsLong);

            return new Location
            {
                ID = ID,
                LocationName = Name,
                GpsLat = Lat,
                GpsLong = Long,
                Altitude = Altitude,
                PreviewDuration = Duration,
                TimezoneName = Timezone
            };
        }
    }
}
